{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "c94e9654-2899-478a-96db-b205a7c16efc",
   "metadata": {},
   "source": [
    "# 一、写代码求解以下题目\n",
    "\n",
    "对以下样本数据进行主成分分析\r",
    "$$\n",
    "X =\n",
    "\\begin{bmatrix}\n",
    "2 & 3 & 3 & 4 & 5 & 7 \\\\\n",
    "2 & 4 & 5 & 5 & 6 & 8\n",
    "\\end{bmatrix}\n",
    "$$\n",
    "\r\n",
    "用PCA的方法将这组二维数据降到一维。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "926a372f-0980-4b50-bb6e-88b771113733",
   "metadata": {},
   "source": [
    "### 导入用到的包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "dfcf4ff2-fbc9-4779-aa44-15a76cd0f5bf",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "651b367b-fa76-47e9-b816-cfd2b9997a1b",
   "metadata": {},
   "source": [
    "### 1.对数据集标准化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "1dc351d6-87af-4129-9fc4-66435bd15450",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[4.]\n",
      " [5.]]\n",
      "[[1.78885438]\n",
      " [2.        ]]\n",
      "标准化后的数据：\n",
      " [[-1.11803399 -0.55901699 -0.55901699  0.          0.55901699  1.67705098]\n",
      " [-1.5        -0.5         0.          0.          0.5         1.5       ]]\n"
     ]
    }
   ],
   "source": [
    "# 假设 X 是一个二维数据矩阵（每行是特征，每列是样本）\n",
    "X = np.array([[2, 3, 3, 4, 5, 7],\n",
    "              [2, 4, 5, 5, 6, 8]])\n",
    "\n",
    "# 1. 计算均值和标准差\n",
    "mean = np.mean(X, axis=1, keepdims=True)  # 按行计算均值\n",
    "print(mean)\n",
    "std = np.std(X, axis=1, ddof=1, keepdims=True)    # 按行计算标准差\n",
    "# std = np.std(X, axis=1, keepdims=True)    # 按行计算标准差\n",
    "print(std)\n",
    "\n",
    "# 2. 进行标准化\n",
    "X_n = (X - mean) / std\n",
    "\n",
    "# 打印结果\n",
    "print(\"标准化后的数据：\\n\", X_n)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "56c18231-6189-4158-931b-0e4f290417f4",
   "metadata": {},
   "source": [
    "### 2.计算协方差阵R"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "afb36805-f323-4d72-97c7-095d38f9f070",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1.         0.95032889]\n",
      " [0.95032889 1.        ]]\n"
     ]
    }
   ],
   "source": [
    "R = 1/5 * X_n @ X_n.T\n",
    "print(R)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d53dd731-bc3d-46ee-8109-daf6491a082d",
   "metadata": {},
   "source": [
    "### 3.计算特征值和特征向量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "61545af2-ca37-4d25-a8ee-8131e72ee320",
   "metadata": {},
   "outputs": [],
   "source": [
    "eigenvalues, eigenvectors = np.linalg.eig(R)\n",
    "max_index = np.argmax(eigenvalues)\n",
    "w = eigenvectors[:, max_index]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ecf5ceff-7e10-4284-b989-56ebd35c94d1",
   "metadata": {},
   "source": [
    "### 4.计算降维后的数据集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "7370a13a-6f2a-4e0e-8155-7459a968f83a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "特征向量的值为 [0.70710678 0.70710678]\n",
      "降维的结果为 [-1.85122959 -0.7488381  -0.39528471  0.          0.7488381   2.24651429]\n"
     ]
    }
   ],
   "source": [
    "print('特征向量的值为', w)\n",
    "# 计算降维后的数据集\n",
    "X_transformed_mine = w @ X_n\n",
    "print('降维的结果为', X_transformed_mine)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a5d4587f-bccc-4dac-a174-8a31f28dc887",
   "metadata": {},
   "source": [
    "## 二、调用API"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "ce010218-9a92-47ca-81e9-c64c0456659d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "降维后的数据：\n",
      " [[-1.85122959]\n",
      " [-0.7488381 ]\n",
      " [-0.39528471]\n",
      " [ 0.        ]\n",
      " [ 0.7488381 ]\n",
      " [ 2.24651429]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "from sklearn.decomposition import PCA\n",
    "\n",
    "# 2. 初始化 PCA，设置主成分数为 1\n",
    "pca = PCA(n_components=1)\n",
    "\n",
    "# 3. 拟合并转换数据\n",
    "X_transformed_api = pca.fit_transform(X_n.T)\n",
    "\n",
    "# 4. 打印结果\n",
    "print(\"降维后的数据：\\n\", X_transformed_api)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b6d598ce-6d91-486a-88a2-d48b919cc395",
   "metadata": {},
   "source": [
    "### 5.结论\n",
    "经过对比自写代码和API的结果，发现二者一致。因此可以证明手写代码计算正确"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
